﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FB.DataAccess.DataInf;
using FB.Utilities;
using System.Data.Objects;

namespace FB.DataAccess
{
    public class VideoDAO : IVideoDAO
    {
        private static FBDATA dataContext;
        
        private IRepository<Video> repository;
        public VideoDAO()
        {
            dataContext = new FBDATA();
            repository = new RepositoryDAO<Video>(dataContext);
        }

        public IEnumerable<Video> GetAllVideo()
        {
            var q = (from m in dataContext.Videos
                     where m.IsPlaylist == false && m.IsDelete == false
                     orderby m.Enable
                     select m).Take(500);
            return q;
        }
        public Video GetVideoByID(Guid id)
        {
            return repository.Find(obj => obj.ID == id).SingleOrDefault();
        }
        public Video GetLastRecord()
        {
            return dataContext.Videos.OrderByDescending(obj => obj.ID).FirstOrDefault();
        }

        public bool UpdateVideo(Video inVideo)
        {
            if (inVideo == null) return false;
            Video upVideo = repository.First(sobj => sobj.ID == inVideo.ID);
            if (upVideo == null) return false;
            upVideo.Title = inVideo.Title;
            upVideo.Description = inVideo.Description;
            upVideo.Enable = inVideo.Enable;
            upVideo.ViewCount = inVideo.ViewCount;
            upVideo.Disliked = inVideo.Disliked;
            upVideo.IsPlaylist = inVideo.IsPlaylist;
            upVideo.LastCheckAliveDate = inVideo.LastCheckAliveDate;
            upVideo.IsDead = inVideo.IsDead;
            upVideo.LastFeedDate = inVideo.LastFeedDate;
            upVideo.IsDelete = inVideo.IsDelete;
            return repository.SaveChanges() > 0;

        }
        public ReturnValue<bool> InsertVideo(Video inVideo)
        {
            if (inVideo == null) return new ReturnValue<bool>(false, "Input data null");
            if (IsVideoExist(inVideo.YoutubeID)) return new ReturnValue<bool>(false, "Video already exist");
            repository.Add(inVideo);
            return new ReturnValue<bool>(repository.SaveChanges() > 0, "Input data null");
        }

        public ReturnValue<Video> InsertVideoAndReturn(Video inVideo)
        {
            if (inVideo == null) return new ReturnValue<Video>(null, "Input value not valid");
            if (IsVideoExist(inVideo.YoutubeID)) return new ReturnValue<Video>(null, "Video already exist");
            Video ret = repository.AddAndReturn (inVideo);
            return new ReturnValue<Video>(ret, "Successfull");
        }

        public bool IsVideoExist(string youtubeVideoID)
        {
            return repository.Exist(video => video.YoutubeID == youtubeVideoID);
        }

        public ReturnValue<bool> DelVideo(Guid id)
        {
            ReturnValue<bool> ret = new ReturnValue<bool>(false, "");
            try
            {
                Video objDel = repository.First(obj => obj.ID == id);
                ret = DelVideo(objDel);
            }
            catch (Exception ex)
            {
                ret.RetValue = false;
                ret.Msg = "Dữ liệu đã được sử dung trong chương trình - không thể xóa !";
            }
            return ret;
        }


        public ReturnValue<bool> DelVideo(Video inVideo)
        {
            ReturnValue<bool> ret = new ReturnValue<bool>(false, "");
            if (inVideo == null)
            {
                ret.Msg = "input null";
                return ret;
            }
            try
            {
                repository.Delete(inVideo);
                ret.RetValue = repository.SaveChanges() > 0;
            }
            catch (System.Exception ex)
            {
                ret.RetValue = false;
                ret.Msg = "Dữ liệu đã được sử dung trong chương trình - không thể xóa !";
            }
            return ret;
        }

        public IEnumerable<View_VideoInCategory> GetVideoByCategory(Guid categoryID, int limit)
        {
            var result = (from v in dataContext.View_VideoInCategory
                          where v.CategoryID == categoryID
                          orderby Guid.NewGuid()
                          select v).Take(limit);
            return result;
        }

        public IEnumerable<Video> GetAllPlaylist()
        {
            return repository.GetQuery().Where(bobj=> bobj.IsPlaylist == true).OrderBy(aobj => aobj.ID);
        }

        public Video GetVideoByYoutubeID(string youtubeID)
        {
            return repository.Find(obj => obj.YoutubeID == youtubeID).SingleOrDefault();
        }

        public void IncreaseViewCount(string itemID)
        {
            Video MyVideo = GetVideoByYoutubeID(itemID);
            if (MyVideo != null)
            {
                MyVideo.ViewCount++;
            }
            UpdateVideo(MyVideo);
        }

        public List<View_VideoTag> GetTagByVideoID(Guid videoID)
        {
            TagDAO ObjDAO = new TagDAO();
            return ObjDAO.GetTagOfVideo(videoID);
        }

        public List<Video> GetRelatedVideoByVideo(string videoYoutubeID, int limit, List<Guid> exceptList)
        {
            Video PlayVideo = GetVideoByYoutubeID(videoYoutubeID);
            var result = dataContext.sp_FB_FindVideo(PlayVideo.Title + PlayVideo.Description, limit);
            return (from m in result
                     where (m.YoutubeID != videoYoutubeID && (!exceptList.Contains(m.ID)))
                     select m).ToList();
        }

        public List<Video> GetVideoByTagId(Guid tagID, int limit, List<Guid>exceptList)
        {
            List<Video> Result = new List<Video>();
            List<View_VideoTag> MessResult = (from m in dataContext.View_VideoTag
                                            where (m.IDTag == tagID && (!exceptList.Contains(m.ID)))
                                             select m).Take(limit).ToList();


            foreach (View_VideoTag item in MessResult)
            {
                Result.Add(new Video(item));
            }
            return Result;
        }

        public List<Video> GetVideoByCateId(Guid cateID, int limit, List<Guid> exceptList)
        {
            List<Video> Result = new List<Video>();
            List<View_VideoInCategory> MessResult = (from m in dataContext.View_VideoInCategory
                                              where (m.CategoryID == cateID && (!exceptList.Contains(m.ID)))
                                              select m).Take(limit).ToList();


            foreach (View_VideoInCategory item in MessResult)
            {
                Result.Add(new Video(item));
            }
            return Result;
        }

        public List<Video> SearchVideo(string keyword, int limit)
        {
            return dataContext.sp_FB_FindVideo(keyword, limit).ToList();
        }

        public Guid? GetOneToEdit()
        {
            Video temp = (from m in dataContext.Videos
                    where m.Enable == false && m.IsDelete == false
                    select m).First();
            if (temp != null)
            {
                return temp.ID;
            }
            else
            {
                return null;
            }
        }

        public Video GetVideo2CheckAlive()
        {
            Video temp = (from m in dataContext.Videos
                          where m.Enable != false && m.IsDead != true && m.IsDelete != true
                          orderby m.LastCheckAliveDate
                          select m).First();
            return temp;
        }
    }
}
